using System.Collections.Concurrent;
using System.Net;
using System.Net.Sockets;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using SocketPorxyServer;
using SuperSocket;
using SuperSocket.Server;

namespace SuperSocketProxy;

public sealed class SocketProxyServer : SuperSocketService<SocketProxyPacket> , IProxyPoolFactory
{
    private readonly ProxyOptions _options;
    private readonly ConcurrentDictionary<IPAddress, ProxyPool> _addresses = new();

    public SocketProxyServer(
        IServiceProvider serviceProvider, 
        IOptions<ServerOptions> serverOptions, 
        IOptions<ProxyOptions> proxyOptions) : base(serviceProvider, serverOptions)
    {
        _options = proxyOptions.Value;
    }

    IEnumerable<ProxyPool> IProxyPoolFactory.GetAll()
    {
        var proxyList = new List<ProxyPool>();
        
        proxyList.AddRange(_addresses.Select(p=> new ProxyPool
        {
            Address = p.Key,
            Username = p.Value.Username,
            Password = p.Value.Password,
        }));

        return proxyList;
    }
    
    ProxyPool IProxyPoolFactory.GetByAddress(IPAddress address)
    {
        if (!_addresses.TryGetValue(address, out var queue))
            throw new Exception();

        if (queue.Count == 0)
            throw new Exception("可用端口不足");
        
        return queue;
    }
    
    protected override ValueTask OnStartedAsync()
    {
        Logger.LogInformation("开始加载局域网ip....");
        
        //获取本机IP 
        var ipAddresses = Dns.GetHostAddresses(Dns.GetHostName()).Where(address => address.AddressFamily == AddressFamily.InterNetwork).ToArray();

        foreach (var address in ipAddresses)
        {
            Logger.LogInformation($"{address}：正在生成端口");
            
            var pool = ProxyPool.NewRandom(address, _options.Username, _options.Password);
            
            _addresses.TryAdd(address, pool);
        }

        if (_options.EnableHttpProxy)
            Logger.LogInformation($"加载所有内网IP完毕共{_addresses.Count}个\r\n已开启http代理");
        else
            Logger.LogInformation($"加载所有内网IP完毕共{_addresses.Count}个\r\n未开启http代理");
        
        return ValueTask.CompletedTask;
    }
}